在講完 React.js 中的基本架構後,今天要來講講要如何在 JSX 中加入 event handler ,既然 React.js 可以說是將 HTML 寫在 JS 的 UI 函式庫,想當然只要是 HTML 支援的 event handler 在 React.js 中一定也都支援,假如讀者對於 event 以及 event handler 有不了解的歡迎閱讀筆者之前寫過的文章來加深自己的觀念。
還記得以前在寫 HTML 的時候是如何寫 event handler 嗎?通常都會寫成底下這個模樣:
<button onclick="handleClick()">我是按鈕</button>
其實 JSX 就跟 HTML 的寫法差不多,差別只在於 onclick
要變成 onClick
而後面的 handler function 要用 {}
包起來因為是個變數,但是有個問題是因為這個 handler function 是寫在元件內,所以要加個 this 才能正確地被呼叫到,所以寫法就會長得像這樣:
class App extends Component {
handleClick() {
alert('我被點擊了')
}
render() {
return <button onClick={this.handleClick}>我是按鈕</button>
}
}
接下來講點應用的部分,大家都知道 React.js 是透過更新 state 的方式來進行畫面的更新,而更新 state 最常用的作法就是利用 event handler 了,這邊來用個簡單的例子來說明如何完成 state 的更新:
class App extends Component {
state = { time: 0 }
handleClick() {
return this.setState(prevState => ({ time: prevState.time++ }))
}
render() {
return (
<div>
<button onClick={this.handleClick}>我是按鈕</button>
<h4>我被點擊{this.state.time}次</h4>
</div>
)
}
}
這時候會發現竟然噴錯了,錯誤原因是因為 setState of undefined
,這個就跟 this 的作用域有關了,因為對於 handleClick()
這個 function 來說,他的 this 並不是元件本身,因此我們必須要先為這個 function 綁定元件的 this 才能進行 setState
的動作,而 this 的作用域如果讀者有任何不了解的可以參考筆者之前寫過的文章。
接下來要來講講如何正確的呼叫 event handler ,其實做法也很簡單,只要在初始化時將也就是 constructor()
中將元件內的 this 透過 bind(this)
的方式讓 handler function 可以正確地被元件綁定起來,寫法如下:
class App extends Component {
state = { time: 0 }
constructor() {
super()
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
return this.setState(prevState => ({ time: ++prevState.time }))
}
render() {
return (
<div>
<button onClick={this.handleClick}>我是按鈕</button>
<h4>我被點擊{this.state.time}次</h4>
</div>
)
}
}
this.handleClick = this.handleClick.bind(this)
這句話的意思就是我初始化一個叫 handleClick
的變數,這個變數的值是將元件內的 handleClick()
綁定元件的 this ,而之後就可以透過 this.handleClick
的方式呼叫到正確的 function 。
還記得 ES6 提出一個非常好用的 function 寫法: arrow function 嗎?接下來要來講講筆者平時在撰寫 event handler 中最常使用的寫法,利用 arrow function 最重要的一項特性:沒有 this ,如此一來 this.handleClick
中的 this 就一定會是元件自身了,這樣就不需要 bind(this)
可以省下很多程式碼是個相當好用的方法。
class App extends Component {
state = { time: 0 }
handleClick = () => (
this.setState(prevState => ({ time: ++prevState.time }))
)
render() {
return (
<div>
<button onClick={this.handleClick}>我是按鈕</button>
<h4>我被點擊{this.state.time}次</h4>
</div>
)
}
}
今天介紹了 JSX 的 event handler ,經過這幾天的介紹不曉得大家有沒有覺得 React.js 其實並沒有想像中那麼難理解呢?其實只要記住一些寫法上的小訣竅就可以用很簡單的方式來完成 event 的串接,同時也讓元件的邏輯變得更好維護。
如果讀者有任何問題歡迎在下面留言給我,沒問題的話明天要來講講雖然跟元件沒什麼關係但在 React.js 中也是個蠻重要的觀念: List and keys 。